package com.ruoyi.web.controller.security;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.security.domain.SecurityTradingCalendar;
import com.ruoyi.security.dto.SecurityDayMinuteTradeDto;
import com.ruoyi.security.dto.SyncSecurityDayMinuteTradeDto;
import com.ruoyi.security.service.ISecurityDayMinuteTradeService;
import com.ruoyi.security.service.ISecurityTimeShareService;
import com.ruoyi.security.service.ISecurityTradingCalendarService;
import com.ruoyi.security.service.impl.SecurityDayMinuteTradeServiceImpl;
import com.ruoyi.security.service.impl.SyncTaskManager;
import com.ruoyi.security.util.DateUtil;
import com.ruoyi.security.vo.SecurityTimeShareVo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.List;

/**
 * @author yeoman
 * @date 2025/4/30 10:43
 * @description 证券日分钟交易
 * @version 1.0
 */
@Controller
@RequestMapping("/security/time-share")
@Validated
public class SecurityTimeShareController extends BaseController {


    @Resource
    private ISecurityTimeShareService securityTimeShareService;

    @Resource
    private ISecurityDayMinuteTradeService securityDayMinuteTradeService;
    
    @Resource
    private ISecurityTradingCalendarService securityTradingCalendarService;
    
    @Resource
    private SyncTaskManager syncTaskManager;

    /**
     * 证券分时图页面
     */
    @RequiresPermissions("security:timeShare:view")
    @GetMapping()
    public String timeShare() {
        return "security/time-share";
    }

    /**
     * 获取证券分时图数据（AJAX接口）
     */
    @RequiresPermissions("security:timeShare:view")
    @GetMapping("/data")
    @ResponseBody
    public AjaxResult getTimeShareData(@RequestParam @NotBlank(message = "代码不能为空") String symbol,
                                      @RequestParam @NotBlank(message = "开始日期不能为空") String startDate,
                                      @RequestParam @NotBlank(message = "结束日期不能为空") String endDate) {
        try {
            logger.info("接收到请求参数 - symbol: {}, startDate: {}, endDate: {}", symbol, startDate, endDate);
            
            // 获取分时图数据
            SecurityTimeShareVo timeShareData = securityTimeShareService.getTimeShareData(symbol, startDate, endDate);
            
            return AjaxResult.success("获取数据成功", timeShareData);
            
        } catch (Exception e) {
            logger.error("获取证券分时数据失败，证券代码：{}，开始日期：{}，结束日期：{}", symbol, startDate, endDate, e);
            return AjaxResult.error("获取数据失败：" + e.getMessage());
        }
    }

    /**
     * 获取无效交易日列表（缺失或不完整的交易日）
     */
    @RequiresPermissions("security:timeShare:view")
    @GetMapping("/invalid-dates")
    @ResponseBody
    public AjaxResult getInvalidTradeDates(@RequestParam @NotBlank(message = "代码不能为空") String symbol,
                                          @RequestParam @NotBlank(message = "开始日期不能为空") String startDate,
                                          @RequestParam @NotBlank(message = "结束日期不能为空") String endDate) {
        try {
            logger.info("获取无效交易日列表，证券代码：{}，开始日期：{}，结束日期：{}", symbol, startDate, endDate);
            
            // 1. 获取交易日列表
            Date start = DateUtil.parseDate(startDate);
            Date end = DateUtil.parseDate(endDate);
            if (start == null || end == null) {
                return AjaxResult.error("日期格式错误");
            }
            List<SecurityTradingCalendar> tradingDays = securityTradingCalendarService.selectTradingDays(start, end);
            
            // 2. 查询交易数据
            SecurityDayMinuteTradeDto dto = new SecurityDayMinuteTradeDto();
            dto.setSymbol(symbol);
            dto.setStratDate(startDate);
            dto.setEndDate(endDate);
            List<com.ruoyi.security.domain.SecurityDayMinuteTrade> tradeList = securityDayMinuteTradeService.list(dto);
            
            // 3. 获取无效交易日列表
            List<String> invalidDates = securityDayMinuteTradeService.getInvalidTradeDates(symbol, tradingDays, tradeList);
            
            return AjaxResult.success("获取成功", invalidDates);
        } catch (Exception e) {
            logger.error("获取无效交易日列表失败，证券代码：{}", symbol, e);
            return AjaxResult.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 同步分时数据（异步，返回任务ID）
     */
    @Log(title = "同步分时数据", businessType = BusinessType.INSERT)
    @RequiresPermissions("security:timeShare:sync")
    @PostMapping("/sync")
    @ResponseBody
    public AjaxResult syncTimeShare(@Validated SyncSecurityDayMinuteTradeDto dto) {
        try {
            logger.info("开始同步分时数据，证券代码：{}，开始日期：{}，结束日期：{}", 
                dto.getSymbol(), dto.getStartDate(), dto.getEndDate());
            
            // 异步执行同步任务，返回任务ID
            String taskId = securityDayMinuteTradeService.syncListAsync(dto);
            
            if (taskId == null) {
                return AjaxResult.success("所选日期范围内的数据已完整，无需同步");
            }
            
            logger.info("同步分时数据任务已提交，任务ID：{}", taskId);
            return AjaxResult.success("同步任务已提交", taskId);
        } catch (Exception e) {
            logger.error("同步分时数据失败，证券代码：{}", dto.getSymbol(), e);
            return AjaxResult.error("同步分时数据失败：" + e.getMessage());
        }
    }
    
    /**
     * 查询同步任务进度
     */
    @RequiresPermissions("security:timeShare:view")
    @GetMapping("/sync/progress")
    @ResponseBody
    public AjaxResult getSyncProgress(@RequestParam @NotBlank(message = "任务ID不能为空") String taskId) {
        try {
            SyncTaskManager.TaskInfo taskInfo = syncTaskManager.getTask(taskId);
            
            if (taskInfo == null) {
                return AjaxResult.error("任务不存在或已过期");
            }
            
            // 构建返回数据
            java.util.Map<String, Object> result = new java.util.HashMap<>();
            result.put("taskId", taskInfo.getTaskId());
            result.put("symbol", taskInfo.getSymbol());
            result.put("totalDays", taskInfo.getTotalDays());
            result.put("syncedDays", taskInfo.getSyncedDays().get());
            result.put("failedDays", taskInfo.getFailedDays().get());
            result.put("status", taskInfo.getStatus());
            result.put("errorMessage", taskInfo.getErrorMessage());
            result.put("currentDate", taskInfo.getCurrentDate());
            result.put("startTime", taskInfo.getStartTime());
            result.put("endTime", taskInfo.getEndTime());
            
            // 计算进度百分比（使用已处理天数）
            int processedDays = taskInfo.getProcessedDays().get();
            double progress = taskInfo.getTotalDays() > 0 ? 
                (double) processedDays / taskInfo.getTotalDays() * 100 : 0;
            result.put("progress", Math.round(progress * 100) / 100.0);
            result.put("processedDays", processedDays);
            
            return AjaxResult.success("获取成功", result);
        } catch (Exception e) {
            logger.error("查询同步任务进度失败，任务ID：{}", taskId, e);
            return AjaxResult.error("查询失败：" + e.getMessage());
        }
    }

}
